/**
 * Copyright 2008 Mathias Doenitz, http://lis.to/
 *
 * This file is part of the lis.to java desktop client. The lis.to java desktop client is free software: you can
 * redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free
 * Software Foundation, either version 3 of the License, or (at your option) any later version.
 *
 * The lis.to java desktop client is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with the lis.to java desktop client.
 * If not, see http://www.gnu.org/licenses/
 */

package listo.client.dragdrop;

import com.google.inject.Inject;
import com.google.inject.Singleton;
import listo.client.ContextManager;
import listo.client.Convert;
import listo.client.model.Context;
import listo.client.model.Task;
import listo.client.model.Tasks;
import listo.client.model.operations.Operation;
import listo.client.model.operations.RepositionTasksOp;
import listo.client.tasklists.TaskList;
import listo.utils.logging.Log;
import org.apache.commons.lang.ArrayUtils;

import javax.swing.*;
import java.awt.datatransfer.Transferable;

@Singleton
public class TaskListTransferHandler extends BaseTransferHandler {

    @Inject
    public TaskListTransferHandler(ContextManager contextManager, Log log) {
        super(contextManager, log);
    }

    //********************************************************************
    //*                             EXPORT
    //********************************************************************

    public int getSourceActions(JComponent c) {
        return MOVE | COPY;
    }

    protected Transferable createTransferable(JComponent c) {
        TaskList list = (TaskList) c;
        return new TaskSelection(new Tasks(list.getSelectedValues()));
    }

    //********************************************************************
    //*                             IMPORT
    //********************************************************************

    @SuppressWarnings({"RedundantIfStatement"})
    public boolean canImport(TransferSupport support) {
        if (!support.isDrop()) return false;

        JList.DropLocation location = (JList.DropLocation) support.getDropLocation();
        TaskList taskList = (TaskList) support.getComponent();
        int dropIx = location.getIndex();
        Task dropTask = taskList.getTaskAt(dropIx);
        if (dropTask == null) return false;

        if (support.isDataFlavorSupported(TaskSelection.TASK_FLAVOR)) {
            taskList.setDropMode(DropMode.INSERT);

            // we can only drop between tasks not on top
            if (!location.isInsert()) return false;

            // we cannot drop right before or right after our current position
            Tasks dragTasks = (Tasks) getSelection(support, TaskSelection.TASK_FLAVOR);
            int[] dragIxs = taskList.indicesOf(dragTasks);
            if (ArrayUtils.contains(dragIxs, dropIx) || ArrayUtils.contains(dragIxs, dropIx - 1)) return false;

            return true;
        }

        return false;
    }

    protected Operation createDropOperation(TransferSupport support) {
        JList.DropLocation location = (JList.DropLocation) support.getDropLocation();
        TaskList taskList = (TaskList) support.getComponent();
        int dropIx = location.getIndex();
        Task dropTask = taskList.getTaskAt(dropIx);

        if (support.isDataFlavorSupported(TaskSelection.TASK_FLAVOR)) {
            Tasks dragTasks = (Tasks) getSelection(support, TaskSelection.TASK_FLAVOR);
            Context currentContext = contextManager.getCurrentContext();
            int pos = currentContext.indexOf(dropTask);
            for (Task dragTask : dragTasks) {
                if (currentContext.indexOf(dragTask) < pos) pos--;
            }

            RepositionTasksOp op = new RepositionTasksOp();
            op.setTasks(Convert.toObjectIds(dragTasks.toArray()));
            op.setPosition(pos);
            return op;
        }

        return null;
    }
}
